home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
TCL1
/
JOHNLOVE
/
C_SOURCE
/
CMYDOC.C
< prev
next >
Wrap
Text File
|
1992-01-17
|
13KB
|
433 lines
/*********************************************************
"CmyDoc.c"
by John A. Love, III [Washington Apple Pi Users' Group]
using Symantec's "THINK C", v 5.0.1
... as derived from their "TCL Starter" files
*********************************************************/
#include <Commands.h>
#include <CApplication.h>
#include <CBartender.h>
#include <CDataFile.h>
#include <CDecorator.h>
#include <CDesktop.h>
#include <CError.h>
#include <CPanorama.h>
#include <CScrollPane.h>
#include <TBUtilities.h>
#include <CWindow.h>
#include <Packages.h>
#include "CmyGlobals.h"
#include "CmyDoc.h"
#include "CmyPane.h"
#define WINDStarter 500 /* Resource ID for WIND template */
extern CApplication *gApplication; /* The application */
extern CBartender *gBartender; /* The menu handling object */
extern CDecorator *gDecorator; /* Window dressing object */
extern CDesktop *gDesktop; /* The enclosure for all windows */
extern CBureaucrat *gGopher; /* The current boss in the chain of command */
extern OSType gSignature; /* The application's signature */
extern CError *gError; /* The global error handler */
void CStarterDoc::IStarterDoc (CApplication *aSupervisor, Boolean printable) {
CDocument::IDocument(aSupervisor, printable);
} /* IStarterDoc */
/* Dispose
**
** This is your document's destruction method.
** If you allocated memory in your initialization method
** or opened temporary files, this is the place to release them.
**
** Be sure to call the default method!
*/
void CStarterDoc::Dispose (void) {
inherited::Dispose();
} /* Dispose */
/* DoCommand
**
** This is the heart of your document.
** In this method, you handle all the commands your document deals with.
**
** Be sure to call the default method to handle the standard
** document commands: cmdClose, cmdSave, cmdSaveAs, cmdRevert,
** cmdPageSetup, cmdPrint, and cmdUndo. To change the way these
** commands are handled, override the appropriate methods instead
** of handling them here.
*/
void CStarterDoc::DoCommand (long theCommand) {
switch (theCommand) {
// your document commands here:
default:
inherited::DoCommand(theCommand);
break;
}
} /* DoCommand */
/* UpdateMenus
**
** In this method you can enable menu commands that apply when
** your document is active.
**
** Be sure to call the inherited method to get the default behavior.
** The inherited method enables these commands: cmdClose, cmdSaveAs,
** cmdSave, cmdRevert, cmdPageSetup, cmdPrint, cmdUndo.
*/
void CStarterDoc::UpdateMenus (void) {
inherited::UpdateMenus();
/* Enable your menu commands here (enable each one with a call to
gBartender->EnableCmd(command_number)). */
} /* UpdateMenus */
/* NewFile
**
** When the user chooses New from the File menu, the CreateDocument()
** method in your Application class will send a newly created document
** this message. This method needs to create a new window, ready to
** work on a new document.
**
** Since this method and the OpenFile() method share the code for creating
** the window, you should use an auxiliary window-building method.
*/
void CStarterDoc::NewFile (void) {
Str255 wTitle; /* Window title string. */
short wCount; /* Index number of new window. */
Str255 wNumber; /* Index number as a string. */
/* BuildWindow() is the method that does the work of creating a window.
** Its parameter should be the data that you want to display in the window.
** Since this is a new window, there's nothing to display. */
BuildWindow(NULL);
// Append an index number to the default name of the window:
itsWindow->GetTitle(wTitle);
wCount = gDecorator->GetWCount();
NumToString(wCount, wNumber);
ConcatPStrings(wTitle, (StringPtr) "\p ");
ConcatPStrings(wTitle, wNumber);
itsWindow->SetTitle(wTitle);
// Send the window a Select() message to make it the active window:
itsWindow->Select();
} /* NewFile */
/* OpenFile
**
** When the user chooses Open╔ from the File menu, the OpenDocument()
** method in your Application class will let the user choose a file
** and then send a newly created document this message. The information
** about the file is in the SFReply record.
**
** In this method, you need to open the file and display its contents
** in a window. This method uses the auxiliary window-building method.
*/
void CStarterDoc::OpenFile (SFReply *macSFReply) {
CDataFile *theFile;
Handle theData = NULL;
Str63 theName;
OSErr theError;
TRY
{
/* Create a file and send it a SFSpecify()
** message to set up the name, volume, and directory. */
theFile = new(CDataFile);
theFile->IDataFile();
theFile->SFSpecify(macSFReply);
/* Be sure to set the instance variable
** so other methods can use the file if they
** need to. This is especially important if
** you leave the file open in this method.
** If you close the file after reading it, you
** should be sure to set itsFile to NULL. */
itsFile = theFile;
/* Send the file an Open() message to open it. You can use the
** ReadSome() or ReadAll() methods to get the contents of the file. */
theFile->Open(fsRdWrPerm);
/* Make sure that the memory request to read the data from
** the file doesn't use up any of our rainy day fund and
** that the GrowMemory() method (in the application) knows
** that it's OK if we couldn't get enough memory. */
theData = theFile->ReadAll(); /* ReadAll() creates the handle */
BuildWindow(theData);
/* In your application, you'll probably store the data in
** some form as an instance variable in your document class.
** For this example, there's no need to save it, so get rid of it. */
DisposHandle(theData);
theData = NULL;
/* In this implementation, we leave the file open. You might
** want to close it after you've read in all the data. */
itsFile->GetName(theName);
itsWindow->SetTitle(theName);
itsWindow->Select(); // Don't forget to make the window active.
}
CATCH
{
/* This exception handler will be executed if an exception occurs
** anywhere within the scope of the TRY block above.
** You should perform any cleanup of things that won't be needed
** since the document could not be opened. By convention,
** the creator of an object is responsible for sending it
** the Dispose message. This means that we should only dispose
** of things that would not be taken care of in Dispose.
** In this case, we just make sure that the Handle theData
** has been disposed of. The exception will propagate up to
** CApplications's exception handler, which handles displaying
** an error alert. */
if (theData) DisposHandle( theData);
}
ENDTRY;
} /* OpenFile */
/* BuildWindow
**
** This is the auxiliary window-building method that the
** NewFile() and OpenFile() methods use to create a window.
**
** In this implementation, the argument is the data to display.
*/
void CStarterDoc::BuildWindow (Handle theData) {
CScrollPane *theScrollPane;
CStarterPane *theMainPane;
/* First create the window and initialize it. The first argument
** is the resource ID of the window. The second argument specifies
** whether the window is a floating window. The third argument is
** the window's enclosure; it should always be gDesktop. The last
** argument is the window's supervisor in the Chain of Command;
** it should always be the Document object. */
itsWindow = new(CWindow);
itsWindow->IWindow(WINDStarter, FALSE, gDesktop, this);
/* After you create the window, you can use the SetSizeRect() message
** to set the window╒s maximum and minimum size. Be sure to set the
** max & min BEFORE you send a PlaceNewWindow() message to the decorator.
**
** The default minimum is 100 by 100 pixels. The default maximum is the
** bounds of GrayRgn() We'll use the defaults. */
/* Our window will contain a ScrollPane, which in turn will contain
** a Panorama. Now, let's create the ScrollPane. */
theScrollPane = new(CScrollPane);
/* You can initialize a scroll pane two ways:
** 1. You can specify all the values
** right in your code, like this.
** 2. You can create a ScPn resource and
** initialize the pane from the information
** in the resource.
*/
theScrollPane->IScrollPane(itsWindow, this, 10, 10, 0, 0,
sizELASTIC, sizELASTIC, TRUE, TRUE, TRUE);
/* The FitToEnclFrame() method makes the scroll pane be as large as
** its enclosure. In this case, the enclosure is the window, so the
** scroll pane will take up the entire window. */
theScrollPane->FitToEnclFrame(TRUE, TRUE);
/* itsMainPane is the document's focus of attention. Some of the standard
** classes (particularly CPrinter) rel on itsMainPane pointing to the main
** pane of your window.
**
** itsGopher specifies which object should become the gopher when the document
** becomes active. By default the document becomes the gopher. It╒s likely
** that your main pane handles commands so you╒ll almost always want to set
** itsGopher to point to the same object as itsMainPane.
**
** Note that the main pane is the panorama in the scroll pane and not
** the scroll pane itself. */
theMainPane = new(CStarterPane);
theMainPane->IStarterPane(
theScrollPane, /* CView */
this, /* CBureaucreat */
0, /* aWidth */
0, /* aHeight */
0, /* aHEncl */
0, /* aVEncl */
sizELASTIC, /* aHSizing */
sizELASTIC /* aVSizing */
);
itsMainPane = theMainPane;
itsGopher = theMainPane;
/* The FitToEnclosure() method makes the pane fit inside the enclosure.
** The inside (or interior) of a scroll pane is defined as
** the area inside the scroll bars. */
theMainPane->FitToEnclosure(TRUE, TRUE);
/* Send the scroll pane an InstallPanorama() message to associate
** the panorama with the scroll pane. */
theScrollPane->InstallPanorama(theMainPane);
/* The Decorator is a global object that takes care of placing and
** sizing windows on the screen. You don't have to use it. */
gDecorator->PlaceNewWindow(itsWindow);
} /* BuildWindow */
/* DoSave
**
** This method handles what happens when the user chooses Save from the
** File menu. This method should return TRUE if the file save was successful.
** If there is no file associated with the document, you should send a
** DoSaveFileAs() message.
*/
Boolean CStarterDoc::DoSave (void) {
/* If you closed your file in your NewFile() method,
** you'll need a different way than this to determine
** if there's a file associated with your document. */
if (itsFile == NULL)
return(DoSaveFileAs());
else {
/* In your application, this is where you'd write
** out your file. if you left it open, send the
** WriteSome() or WriteAll() mesages to itsFile. */
dirty = FALSE; /* Document is no longer dirty */
gBartender->DisableCmd(cmdSave);
return(TRUE); /* Save was successful */
}
} /* DoSave */
/* DoSaveAs
**
** This method handles what happens when the user chooses Save As╔ from
** File menu. The default DoCommand() method for documents sends a DoSaveFileAs()
** message which displays a standard put file dialog and sends this message.
** The SFReply record contains all the information about the file you're about
** to create.
*/
Boolean CStarterDoc::DoSaveAs (SFReply *macSFReply) {
/* If there's a file associated with this document already, close it.
** The Dispose() method for files sends a Close() message to the file
** before releasing its memory. */
if (itsFile != NULL)
itsFile->Dispose();
// Create a new file, and then save it normally:
itsFile = new(CDataFile);
((CDataFile *)itsFile)->IDataFile();
itsFile->SFSpecify(macSFReply);
itsFile->CreateNew(gSignature, 'TEXT');
itsFile->Open(fsRdWrPerm);
itsWindow->SetTitle(macSFReply->fName);
return( DoSave() );
} /* DoSaveAs */
/* DoRevert
**
** If your application supports the Revert command, this method
** should close the current file (without writing anything out)
** and read the last saved version of the file.
*/
void CStarterDoc::DoRevert (void) {
} /* DoRevert */
/* end: "CmyDoc.c" */